feat(connections): disconnect, stranding guard, and Set-a-password CTA - #42
Merged
Conversation
PR-B of two for #39. Builds on the Connect flow from #41 to close out the issue: removal of links, the safety rule, and the OAuth-first password on-ramp. - Plumb has_usable_password from /auth/me into the auth context. Default to false on missing/stale responses so the UI stays conservative. - Disconnect button per linked provider. Disabled with an inline hint ("You'd have no way to sign in. Set a password first or link another provider.") when removing it would strand the user. Mirrors the server-side rule so users don't have to click to learn it's blocked: canUnlink = otherConnections.length > 0 || (hasUsablePassword && email) - DELETE /auth/me/connections/{provider} on click. 204 refreshes the list + auth state and toasts success. The 409 unlink_would_strand_user response renders the message + remediation list inline; remediation strings matching /set a password/ get a "Start now" Link pointing at /forgot-password?email=<theirs>. The 404 connection_not_found response refreshes the list and shows a generic toast. - "Set a password" CTA on /profile when has_usable_password=false, linking to /forgot-password?email=<theirs>. The forgot-password route now reads ?email= via validateSearch and prefills the input; the authenticated-user guard relaxes when ?email= is present so the CTA works without forcing a logout. Closes the frontend portion of #39 once both PRs are on main.
✅ Deploy Preview for criticalbit-auth-web ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR-B of two for #39. Builds on #41 (Connect flow) to close out the frontend portion of the issue.
Summary
has_usable_passwordfrom/auth/methrough the auth context (defaults tofalseon missing/stale responses)./profile. Disabled with an inline hint ("You'd have no way to sign in. Set a password first or link another provider.") when removing it would strand the user — mirrors the server-side rule client-side so users don't have to click to learn it's blocked:DELETE /auth/me/connections/{provider}on click:/auth/me/connections+/auth/me, toast "Disconnected ."unlink_would_strand_user→ render the message + remediation list inline (amber alert). Remediation strings matching/set a password/get a "Start now" Link to/forgot-password?email=<email>. Re-syncs connections + auth in case the server saw a different reality.connection_not_found→ refresh connections, toast "That connection is already disconnected."has_usable_password=false, linking to/forgot-password?email=<email>.forgot-passwordroute now accepts?email=viavalidateSearchand prefills the input. The "authenticated user → /profile" guard relaxes when?email=is present so the CTA works without forcing a logout.Closes
Together with #41, the frontend portion of #39 (Steam associate flow + connect/disconnect settings UI) is done.
Test plan
Unit (vitest, 6 new tests, 45 total — all passing)
forgot-password-page.test.tsx— empty default,?email=prefill.profile-page.test.tsx— Disconnect disabled with helper text when stranding, DELETE on click + list refresh + success toast, 409 → rendered remediation list with "Start now" Link, "Set a password" CTA visible whenhas_usable_password=false.hasUsablePasswordfield (defaultfalsefor unauth,truefor the existing auth fixtures).What's not in this PR
Reviewer checklist
pnpm test:runhas_usable_password=falseand only Google linked → Disconnect shows but is disabled with the "no way to sign in" hint, and the "Set a password" CTA appears below./forgot-passwordwith the email prefilled.